%{
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define DATE_FORMAT ("%Y/%B/%d\t%T  (%Z %z)")
#define ARRAY_SZ (256)

char* datestring = NULL;

char** types;
char** damages;
char** monmons;
int *itypes, *idamages, *imonmons;
int iitypes, iidamages, iimonmons;
%}

%debug

%union {char* s; int i;}

%token <s> TYPE 
%token <s> DAMAGE
%token <s> MONMON
%token <i> INT
%token THE_END
%token DEFINE
%token IFNDEF
%token ENDIF

%initial-action {
	types = calloc(ARRAY_SZ, sizeof(char*));
	damages = calloc(ARRAY_SZ, sizeof(char*));
	monmons = calloc(ARRAY_SZ, sizeof(char*));
	itypes = calloc(ARRAY_SZ, sizeof(int));
	idamages = calloc(ARRAY_SZ, sizeof(int));
	imonmons = calloc(ARRAY_SZ, sizeof(int));
	iitypes = 0;
	iidamages = 0;
	iimonmons = 0;
}
%%

input: IFNDEF DEFINE definitions ENDIF {
	YYACCEPT;
};

definitions: DEFINE TYPE INT  { asprintf(&(types[iitypes]), "%s", $2); itypes[iitypes++] = $3; }
| DEFINE DAMAGE INT           { asprintf(&(damages[iidamages]), "%s", $2); idamages[iidamages++] = $3; }
| DEFINE MONMON INT           { asprintf(&(monmons[iimonmons]), "%s", $2); imonmons[iimonmons++] = $3; }
| definitions definitions 	  {  }
;

%%
extern int yylineno;
extern char* yytext;
int yyerror(char *s, int lineNumber) {
  fprintf(stderr, "Error: %s at %d: '%s'\n", s, yylineno, yytext);
  return 0;
}

int main(int argc, char** argv) {
	int i = 0;
	time_t curtime = time((time_t*)0);
	datestring = calloc(ARRAY_SZ, sizeof(char));
	strftime(datestring, ARRAY_SZ, DATE_FORMAT, localtime(&curtime));

	FILE* in_file = fopen("nhsrc/monattk.h", "r");
	yyrestart(in_file);
	yyparse();
	fclose(in_file);
	
	FILE *out = fopen("MonsterAttack.java", "w");
	fprintf(out, 
"/**\n\
* Automatically generated on %s\n\
**/\n\
package termint.game.monsters;\n\
public class MonsterAttack {\n\
\tpublic MonsterAttack(Type type, Damage damageType, int damageN, int damageD) {\n\
\t}\n\
\n", datestring);
	fprintf(out, "\tpublic enum Type {\n\t\t");
	for (i = 0; i < iitypes - 1; i++) 
		fprintf(out, "%s, ", types[i]); 
//		fprintf(out, "%s(%i), ", types[i], itypes[i]); 
	fprintf(out, "%s;\n", types[iitypes-1]);
//	fprintf(out, "%s(%i);\n", types[iitypes-1], itypes[iitypes-1]);
//	fprintf(out, "\t\tprivate int i;\n\t\tprivate Type(int i) { this.i = i; }\n");
	fprintf(out, "\t}\n\n");
	
	fprintf(out, "\tpublic enum Damage {\n\t\t");
	for (i = 0; i < iidamages - 1; i++) 
		fprintf(out, "%s, ", damages[i]); 
//		fprintf(out, "%s(%i), ", damages[i], idamages[i]); 
	fprintf(out, "%s;\n", damages[iidamages-1]);
//	fprintf(out, "%s(%i);\n", damages[iidamages-1], idamages[iidamages-1]);
//	fprintf(out, "\t\tprivate int i;\n\t\tprivate Damage(int i) { this.i = i; }\n");
	fprintf(out, "\t}\n\n");
	
	fprintf(out, "\tpublic enum MonsterVsMonster {\n\t\t");
	for (i = 0; i < iimonmons - 1; i++) 
		fprintf(out, "%s, ", monmons[i]); 
//		fprintf(out, "%s(%i), ", monmons[i], imonmons[i]); 
	fprintf(out, "%s;\n", monmons[iimonmons-1]);
//	fprintf(out, "%s(%i);\n", monmons[iimonmons-1], imonmons[iimonmons-1]);
//	fprintf(out, "\t\tprivate int i;\n\t\tpublic MonsterVsMonster(int i) { this.i = i; }\n");
	fprintf(out, "\t}\n\n");

	fprintf(out, "}\n");
	fclose(out);
	
	printf("Done\n");
	return 0;
}
